/**
 *	@file	pgear_radio.c
 *	@brief	ポケギア　ラジオアプリ
 *	@author	Miyuki Iwasawa
 *	@date	07.06.21
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "field/eventflag.h"
#include "field/evwkdef.h"
#include "field/syswork.h"
#include "field/zonedata.h"
#include "fielddata/script/saveflag.h"
#include "fielddata/maptable/zone_id.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "pgradio_sys.h"
#include "pgradio_bg.h"
#include "pgradio_sub.h"
#include "pgradio_key.h"

//プロトタイプ宣言　グローバル
//================================================================
///オーバーレイプロセス定義
PROC_RESULT PGearRadioProc_Init( PROC *proc,int *seq);
PROC_RESULT PGearRadioProc_Main( PROC *proc,int *seq);
PROC_RESULT PGearRadioProc_End( PROC *proc,int *seq);

//プロトタイプ宣言　ローカル
//
static void radio_InitDataSet(PGRADIO_SYS_WORK* wk);
static void radio_LastDataSet(PGRADIO_SYS_WORK* wk);

static u8 radio_ChannelAreaGet(PGRADIO_SYS_WORK* wk);
static int radioseq_AppInit(PGRADIO_SYS_WORK* wk);
static int radioseq_AppMain(PGRADIO_SYS_WORK* wk);
static int radioseq_AppEnd(PGRADIO_SYS_WORK* wk);
static int radioseq_AllFadeIn(PGRADIO_SYS_WORK* wk);
static int radioseq_AllFadeOut(PGRADIO_SYS_WORK* wk);
static int radioseq_ViewFadeIn(PGRADIO_SYS_WORK* wk);
static int radioseq_ViewFadeOut(PGRADIO_SYS_WORK* wk);




//================================================================
/**
 *	@brief	ポケギア マッププロセス初期化
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return	処理状況
 */
PROC_RESULT PGearRadioProc_Init( PROC *proc,int *seq)
{
	PGRADIO_SYS_WORK *wk = NULL;
	PGEAR_SYS_WORK * sys_wk = (PGEAR_SYS_WORK*)PROC_GetParentWork(proc);

	//ワークエリア取得
	HeapStatePush();

	//ヒープ作成
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_PGEAR_APP,0x20000);

	wk = PROC_AllocWork( proc,sizeof(PGRADIO_SYS_WORK),HEAPID_PGEAR_APP);
	memset(wk,0,sizeof(PGRADIO_SYS_WORK));

	//パラメータ引継ぎ
	wk->sys = sys_wk;
	wk->heapID = HEAPID_PGEAR_APP;

	//サウンド引継ぎ設定
//	Snd_DataSetByScene( SND_SCENE_SUB_TOWNMAP, 0, 0 );

	//初期パラメータゲット
	radio_InitDataSet(wk);

	return PROC_RES_FINISH;
}

/**
 *	@brief	ポケギア　マッププロセスメイン
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearRadioProc_Main(PROC* proc,int *seq)
{
	PGRADIO_SYS_WORK* wk = PROC_GetWork(proc);

	switch(*seq){
	case PGRADIO_SEQ_INIT:
		*seq = radioseq_AppInit(wk);
		break;
	case PGRADIO_SEQ_MAIN:
		*seq = radioseq_AppMain(wk);
		break;
	case PGRADIO_SEQ_END:
		*seq = radioseq_AppEnd(wk);
		break;
	case PGRADIO_SEQ_ALL_FADEIN:
		*seq = radioseq_AllFadeIn(wk);
		break;
	case PGRADIO_SEQ_ALL_FADEOUT:
		*seq = radioseq_AllFadeOut(wk);
		break;
	case PGRADIO_SEQ_VIEW_FADEIN:
		*seq = radioseq_ViewFadeIn(wk);
		break;
	case PGRADIO_SEQ_VIEW_FADEOUT:
		*seq = radioseq_ViewFadeOut(wk);
		break;
	case PGRADIO_SEQ_APP_EXIT:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	ポケギア　メインプロセス終了
 *
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearRadioProc_End(PROC* proc,int* seq)
{
	int heapID = 0;
	PGRADIO_SYS_WORK* wk = PROC_GetWork(proc);

	//セーブデータ反映
	radio_LastDataSet(wk);

	//アプリケーション初回呼び出し終了フラグを立てておく
	wk->sys->call_end = 1;

	//ワークエリア開放
	heapID = wk->heapID;
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(heapID);
	sys_DeleteHeap(heapID);

	return PROC_RES_FINISH;
}

/**
 *	@brief	アプリ初期化データ取得
 */
static void radio_InitDataSet(PGRADIO_SYS_WORK* wk)
{
	//システムにアプリワークポインタを通知
	wk->sys->app_vwork = (void*)wk;

	//システムにSysKey2AppKey描画の切替関数ポインタを通知
	wk->sys->to_akey_func = PGRadioSub_ToKeyChange;
	wk->sys->to_touch_func = PGRadioSub_ToTouchChange;

	//現在の選択スキンを取得
	wk->skin = PGearSv_GetSkin(wk->sys->pg_save);

//	wk->skin = 0;
	IWASAWA_PRINT(" PokeGear Skin = %d\n",wk->skin);

	PGearSv_GetRadioChSelectPos(wk->sys->pg_save,&(wk->x),&(wk->y));
	wk->sw_st = SW_MAX-1;

	wk->area_id = radio_ChannelAreaGet(wk);

	wk->ch_id = RADIO_CHANNEL_NONE;

	wk->old_bgm = Snd_NowBgmNoGet();
}

/**
 *	@brief	セーブデータ反映
 */
static void radio_LastDataSet(PGRADIO_SYS_WORK* wk)
{

	PGearSv_SetRadioChSelectPos(wk->sys->pg_save,wk->x,wk->y);
	wk->sys->to_akey_func = NULL;
	wk->sys->to_touch_func = NULL;
}

/**
 *	@brief	アルフの遺跡チェック
 */
static BOOL radio_SpecialZoneCheck(u16 zone,u8 mode)
{
	int i;
	static const u16 SpZoneAlf[] = {
		ZONE_ID_D24R0205,
		ZONE_ID_D24R0211,
		ZONE_ID_D24R0216,
		ZONE_ID_D24R0217,
		ZONE_ID_D24R0218
	};
	static const u16 SpZoneAjitoKaidenpa[] = {
		//チョウジタウン
		ZONE_ID_T28,
		ZONE_ID_T28R0201,
		ZONE_ID_T28GYM0101,
		ZONE_ID_T28GYM0102,
		ZONE_ID_T28GYM0103,
		ZONE_ID_T28PC0101,
		ZONE_ID_T28PC0102,
		//ロケット団アジト
		ZONE_ID_D35R0101,
		ZONE_ID_D35R0102,
		ZONE_ID_D35R0103,
		ZONE_ID_D35R0104,
		//43番道路
		ZONE_ID_R43,
		ZONE_ID_R43R0101,
		ZONE_ID_R43R0201,
		//怒りの湖
		ZONE_ID_T29,
		ZONE_ID_T29R0101,
		ZONE_ID_T29R0201,
	};
	static const u16* tbl[] = {SpZoneAlf,SpZoneAjitoKaidenpa};
	static const u8 tbl_num[] = {NELEMS(SpZoneAlf),NELEMS(SpZoneAjitoKaidenpa)};
	for(i = 0;i < tbl_num[mode];i++){
		if(tbl[mode][i] == zone){
			return TRUE;
		}
	}
	return FALSE;
}

/**
 *	@brief	ラジオの放送エリア取得
 */
static u8 radio_ChannelAreaGet(PGRADIO_SYS_WORK* wk)
{
	u16 zone = wk->sys->param->player_zone;

	//圏外か？
	if(!ZoneData_GetEnableRadioFlag(zone)){
		return RADIO_AREA_KANTO_NONE;
	}
	//アルフの遺跡マップ？
	if(radio_SpecialZoneCheck(zone,0)){
		return RADIO_AREA_ALF;
	}
	if(ZoneData_IsKanto(zone)){	//カントー
		//発電所クリア前？
		if(!EventWork_CheckEventFlag(wk->sys->ev_save,FE_HATSUDENSYO_CLEAR)){
			return RADIO_AREA_KANTO_NONE;
		}
		//拡張した？
		if(EventWork_CheckEventFlag(wk->sys->ev_save,FE_RADIO_POWER_UP)){
			return RADIO_AREA_KANTO_EX;
		}
		return RADIO_AREA_KANTO;
	}else{	//ジョウト
		//アジト怪電波チェック
		if(radio_SpecialZoneCheck(zone,1) && (!EventWork_CheckEventFlag(wk->sys->ev_save,FE_D35_RAJITO_END))){
			return RADIO_AREA_AJITO;
		}

		//ラジオ塔占拠イベント中？
		if(SysWork_CheckDuaringTheRadioTowerEvent(wk->sys->ev_save)){
			return RADIO_AREA_ROCKET;
		}
		return RADIO_AREA_JOHTO;
	}
	return RADIO_AREA_JOHTO;
}

/**
 *	@brief	ポケギアマップ　シーケンス初期化
 */
static int radioseq_AppInit(PGRADIO_SYS_WORK* wk)
{
	if(!PGRadio_AppInit(wk)){
		return PGRADIO_SEQ_INIT;
	}

	if(wk->sys->call_end){
		return PGRADIO_SEQ_VIEW_FADEIN;
	}else{
		return PGRADIO_SEQ_ALL_FADEIN;
	}
}

/**
 *	@brief	ポケギアマップ　シーケンス終了
 */
static int radioseq_AppMain(PGRADIO_SYS_WORK* wk)
{
	int ret = PG_NEXT_NULL;
	BOOL touch_f = FALSE;

	ret = PGRadioKey_ContTouch(wk,&touch_f);

	if(!touch_f){
		PGFrame_ChangeKeyModeCheck(wk->sys);

		if(wk->sys->control == PGCONT_SYS){
			ret = PGFrame_SysKeyControl(wk->sys);
		}else{
			ret = PGRadioKey_ContKey(wk);
		}
	}
	switch(ret){
	case PG_NEXT_NULL:
		break;
	case PG_NEXT_EXIT:
		wk->sys->next_mode = ret;
		return PGRADIO_SEQ_ALL_FADEOUT;
	case PG_NEXT_APP_SEQ:
		return PGRADIO_SEQ_LIST_SELECT;
	default:
		wk->sys->next_mode = ret;
		return PGRADIO_SEQ_VIEW_FADEOUT;
	}
	return PGRADIO_SEQ_MAIN;
}

/**
 *	@brief	ポケギアマップ　シーケンス終了
 */
static int radioseq_AppEnd(PGRADIO_SYS_WORK* wk)
{
	if(!PGRadio_AppEnd(wk)){
		return PGRADIO_SEQ_END;
	}

	return PGRADIO_SEQ_APP_EXIT;
}

/**
 *	@brief	ポケギアマップ　フェードイン
 */
static int radioseq_AllFadeIn(PGRADIO_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEIN,
				WIPE_TYPE_FADEIN,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		//BGの表示をOnにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_ON);
		}
		//初期パレットを転送
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_BG,16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,0,0x0000);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_OBJ,16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,0,0x0000);
		PaletteFadeTrans( wk->sys->palAnm );
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);

		GF_Disp_GX_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);
		GF_Disp_GXS_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);

		//BGM止める
		Snd_BgmStop(Snd_NowBgmNoGet(),COMM_BRIGHTNESS_SYNC);
		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		PGRadioSub_FirstProgSet(wk);
		wk->main_seq = 0;
		return PGRADIO_SEQ_MAIN;
	}

	return PGRADIO_SEQ_ALL_FADEIN;
}
/**
 *	@brief	ポケギアマップ　フェードアウト
 */
static int radioseq_AllFadeOut(PGRADIO_SYS_WORK* wk)
{
	int i;
	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEOUT,
				WIPE_TYPE_FADEOUT,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		PGRadioSub_ProgramEnd(wk);

		//BGの表示をOffにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_OFF);
		}
		wk->main_seq = 0;
		return PGRADIO_SEQ_END;
	}

	return PGRADIO_SEQ_ALL_FADEOUT;
}

/**
 *	@brief	ポケギアマップ　アプリ切替フェードイン
 */
static int radioseq_ViewFadeIn(PGRADIO_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);

		PGRadioSub_GuideScrollSet(wk,0);
		wk->sys->palEvy = 0;

		//BG123の表示をOnにする
		for(i = 0;i < 3;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME1_M+i,VISIBLE_ON);
		}
		//Brightnessを解除する
		SetBrightness(BRIGHTNESS_NORMAL,
				(PLANEMASK_BG1 | PLANEMASK_BG2 | PLANEMASK_BG3),MASK_MAIN_DISPLAY);

		Snd_BgmStop(Snd_NowBgmNoGet(),COMM_BRIGHTNESS_SYNC);
		wk->main_seq++;
		break;
	case 1:
		if(	!PGFrame_MainPalFadeWait(wk->sys,0) ||
			!PGRadioSub_GuideScrollWait(wk,0)){
			break;
		}
		wk->main_seq++;
		break;
	case 2:
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);
		wk->sys->palEvy = 0;

		PGRadioSub_FirstProgSet(wk);
		wk->main_seq = 0;
		return PGRADIO_SEQ_MAIN;
	}

	return PGRADIO_SEQ_VIEW_FADEIN;
}
/**
 *	@brief	ポケギアマップ　アプリ切替フェードアウト
 */
static int radioseq_ViewFadeOut(PGRADIO_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		PGRadioSub_GuideScrollSet(wk,1);
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);
		wk->sys->palEvy = 0;
		wk->main_seq++;
		break;
	case 1:
		if(	!PGFrame_MainPalFadeWait(wk->sys,1) ||
			!PGRadioSub_GuideScrollWait(wk,1)){
			break;
		}
		wk->main_seq++;
		break;
	case 2:
		//アプリ用パレットを塗りつぶす
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_BG,16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,16,0x0000);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_OBJ,16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,16,0x0000);
		PaletteFadeTrans( wk->sys->palAnm );

		PGRadioSub_ProgramEnd(wk);

		//BG123の表示をOffにする
		for(i = 0;i < 3;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME1_M+i,VISIBLE_OFF);
			GF_BGL_VisibleSet(GF_BGL_FRAME1_S+i,VISIBLE_OFF);
		}
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);
		wk->sys->palEvy = 0;
		wk->main_seq = 0;
		return PGRADIO_SEQ_END;
	}

	return PGRADIO_SEQ_VIEW_FADEOUT;
}